package com.pat.jrgwt.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ProfitLossesPerformance extends BaseTableView
{

//    protected FlexTable m_table = new FlexTable();
    
    protected final double m_beginningEquity = 10000000;
    protected final double m_leverage = 5;

    protected double m_startIndex = 100;
    protected double m_startAkkProfit = 0;
    protected double m_startMaxProfit = 100;
    protected double m_startDd = 0;
    protected double m_startMaxDd = 0;
    
    protected double m_unlevelMaxProfit = 0;
    protected double m_unlevelAkkProfit = 0;
    protected double m_unlevDd = 0;
    protected double m_unlevMaxDd = 0;
    
    protected double m_levAkkProfit = 0;
    protected double m_levIndex = 0;
    protected double m_levMaxProfit = 0;
    protected double m_levDd = 0;
    protected double m_levMaxDd = 0;


    private static class SingletonHolder
    {
        private static final ProfitLossesPerformance instance = new ProfitLossesPerformance();
    }

    public static ProfitLossesPerformance getInstance()
    {
        return SingletonHolder.instance;
    }

    private ProfitLossesPerformance()
    {
        super();
        setLabel("P/L Performance");
        m_arCellValues = new double[m_arRowLabels.length][m_arHeaders.length];
        m_valueFormatter = NumberFormat.getFormat("###,###,##0.0000");

    }

    @Override
    public void drawValues()
    {
        super.drawValues();
        drawFooter();
    }

    protected void drawFooter()
    {
        m_table.setText(13, 5, m_valueFormatter.format(m_startAkkProfit));
        m_table.setText(13, 8, m_valueFormatter.format(m_startIndex));
        m_table.setText(13, 9, m_valueFormatter.format(m_startMaxProfit));
        m_table.setText(13, 10, m_valueFormatter.format(m_startDd));
        m_table.setText(13, 11, m_valueFormatter.format(m_startMaxDd));

        m_table.setText(14, 5, m_valueFormatter.format(m_unlevelAkkProfit));
        m_table.setText(14, 9, m_valueFormatter.format(m_unlevelMaxProfit));
        m_table.setText(14, 10, m_valueFormatter.format(m_unlevDd));
        m_table.setText(14, 11, m_valueFormatter.format(m_unlevMaxDd));

        m_table.setText(15, 5, m_valueFormatter.format(m_levAkkProfit));
        m_table.setText(15, 8, m_valueFormatter.format(m_levIndex));
        m_table.setText(15, 9, m_valueFormatter.format(m_levMaxProfit));
        m_table.setText(15, 10, m_valueFormatter.format(m_levDd));
        m_table.setText(15, 11, m_valueFormatter.format(m_levMaxDd));
    }

    // public ProfitLossesPerformance()
    // {
    // VerticalPanel panel = new VerticalPanel();
    // Label lbl = new Label("P/L Performance");
    // lbl.setStylePrimaryName("cellBold");
    // panel.add(lbl);
    // panel.add(m_table);
    //
    // formatTable();
    // clearValues();
    //
    // initWidget(panel);
    // }

    protected int m_monthRowStartsAt = 4;
    protected NumberFormat m_nf = NumberFormat.getFormat("###,###,##0.000");

//    private void clearValues()
//    {
//        int columns = m_table.getCellCount(0);
//        for( int col = 1; col < columns; col++ )
//        {
//            for( int row = 0; row < 12; row++ )
//            {
//                m_table.setText(row + m_monthRowStartsAt, col, "0.0");
//            }
//        }
//    }
//
//    private void formatTable()
//    {
//        m_table.setBorderWidth(1);
//
//        String[] arHeaders = new String[] { "Einsatz", "Sum", "On equity", "Leverage", "Akk. Profit","Rendite 1", "Rendite 2", "Index", "Max. Profit", "DD", "Max-DD" };
//
//        final YearSelector ys = new YearSelector();
//        ys.addYearChangeHandler(new ChangeHandler()
//        {
//
//            @Override
//            public void onChange(ChangeEvent event)
//            {
//                Window.alert("Changed " + ys.getSelectedYear());
//            }
//        });
//        m_table.setWidget(0, 0, ys);
//        for( int column = 1; column < arHeaders.length; column++ )
//        {
//            m_table.setText(0, column, arHeaders[column - 1]);
//            m_table.getCellFormatter().setStylePrimaryName(0, column,
//                    "cellHeader");
//        }
//
//        for( int month = 1; month < 13; month++ )
//        {
//            m_table.setText(month + m_monthRowStartsAt - 1, 0, "" + month);
//        }
//    }

    @Override
    public void recalculate()
    {
//        Window.alert("Calculating sum for FxPips...");
        final ArchivePerf archivePerf = ArchivePerf.getInstance();
        final FxPipsView pipsView = FxPipsView.getInstance();
        final FxWeighting fxWeighting = FxWeighting.getInstance();
        final EuroConversion euroConversion = EuroConversion.getInstance();
        final double perfDd = 100000;
        
        double start = 0;
        double sumFx = 0;
        double onEquity = 0;
        double leverage = 0;
        double akkProfit = 0;
        double rendite1 = 0;
        double rendite2 = 0;
        double index = 0;
        double maxProfit = 0;
        double dd = 0;
        double maxDd = 0;

        // To use in next inerations
        double prevAkkProfit = 0; 
        double prevIndex = 0;
//        double prevMaxProfit = 0;
        double maxIndex = 0;
        double maxMaxDd = 0;
            
        m_startAkkProfit = m_beginningEquity;
        
        m_unlevelMaxProfit = archivePerf.getValueBy(2010, 12, ArchivePerf.SumColumn);
        m_unlevDd = archivePerf.getValueBy(2010, 12, ArchivePerf.DrawdownColumn);
        m_unlevMaxDd = archivePerf.getValueBy(2010, 12, ArchivePerf.MaxDdColumn);
        m_unlevelAkkProfit = m_startAkkProfit * m_unlevelMaxProfit / 100;
        
        m_levMaxProfit = (m_unlevelMaxProfit - m_startMaxProfit) * m_leverage + m_startMaxProfit;
        m_levDd = m_unlevDd * m_leverage;
        m_levMaxDd = m_unlevMaxDd * m_leverage;
        m_levAkkProfit = (m_unlevelAkkProfit - m_startAkkProfit) * m_leverage + m_startAkkProfit;
        m_levIndex = m_levAkkProfit / 100000;

        prevIndex = m_levAkkProfit / 100000;
        prevAkkProfit = m_levAkkProfit;
//        prevMaxProfit = m_levMaxProfit;
        maxIndex = m_levIndex;
        maxMaxDd = m_levMaxDd > m_unlevMaxDd ? m_levMaxDd : m_unlevMaxDd;
        
//        m_arCellValues = new double[getDataRows()][getDataColumns()];
        // Go for months
        for( int month = 1; month <= getDataRows(); month++ )
        {
            start = fxWeighting.getSafe(month, 3) * perfDd;
            start += fxWeighting.getSafe(month, 6) * perfDd / euroConversion.getRatio("EURUSD", month);
            start += fxWeighting.getSafe(month, 7) * perfDd / euroConversion.getRatio("EURNZD", month);
            start += fxWeighting.getSafe(month, 8) * perfDd / euroConversion.getRatio("EURGBP", month);
            setAt(month, 1, start);
            
            // Sum Fx-Pips EUR
            sumFx = pipsView.getSumForMonth(month);
//          GWT.log("FxPips for month: " + (i+1) + " = " + sum);
            setAt(month, 2, sumFx);
            
            onEquity = sumFx == 0 ? 0 : sumFx / start * m_beginningEquity;
            setAt(month, 3, onEquity);
            
            leverage = onEquity * m_leverage;
            setAt(month, 4, leverage);
            
            // Calculate current akkProfit using previous value of akkProfit
            akkProfit = leverage == 0 ? 0 : prevAkkProfit + leverage;
            setAt(month, 5, akkProfit);
            
            rendite1 = leverage == 0 ? 0 : leverage / prevAkkProfit;
            setAt(month, 6, rendite1);

            rendite2 = leverage == 0 ? 0 : leverage / m_beginningEquity;
            setAt(month, 7, rendite2);
            
            index = leverage == 0 ? 0 : prevIndex * (1 + rendite1);
            setAt(month, 8, index);

            if( index > maxIndex )
            {
                maxIndex = index;
            }

            // Calculate maxProfit if there is data
            maxProfit = 0;
//            GWT.log("Max index at " + month + ": " + maxIndex + ", lev maxProfit: " + m_levMaxProfit);
            if( leverage != 0 )
            {
                maxProfit = m_levMaxProfit > maxIndex ? m_levMaxProfit : maxIndex;
            }
            setAt(month, 9, maxProfit);
            
//            GWT.log("maxProfit < prevMaxProfit: " + maxProfit + " < " + prevMaxProfit);
            dd = index < prevIndex ? maxProfit - index : 0;
            setAt(month, 10, dd);
            
            maxDd = 0;
            if( leverage != 0 )
            {
                maxDd = m_levMaxDd > maxMaxDd ? m_levMaxDd : maxMaxDd;
            }
            setAt(month, 11, maxDd);
            
            // Save current akkProfit to use in next iteration
            prevAkkProfit = akkProfit;
            prevIndex = index;
//            prevMaxProfit = maxProfit;
            
            if( maxDd > maxMaxDd )
            {
                maxMaxDd = maxDd;
            }
        }
        
//      GWT.log("Got 2010-12 sum: " + m_startMaxProfig);
        
        drawValues();
    }

    @Override
    protected void setHeaders()
    {
        m_arHeaders = new String[] { "Einsatz", "Sum", "On equity", "Leverage", "Akk. Profit","Rendite 1", "Rendite 2", "Index", "Max. Profit", "DD", "Max-DD" };
//        GWT.log("setHeaders(): m_arHeaders.length: " + m_arHeaders.length);

    }

    @Override
    protected void setRowLabels()
    {
        m_arRowLabels = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec" };
//        GWT.log("setRowLabels(): m_arRowLabels.length: " + m_arRowLabels.length);
    }

}
